Add new sysctl to return runtime information about physical CPU utilization.
authorSteven Hand <steven@xensource.com>
Wed, 27 Jun 2007 20:01:08 +0000 (21:01 +0100)
committerSteven Hand <steven@xensource.com>
Wed, 27 Jun 2007 20:01:08 +0000 (21:01 +0100)
Signed-off-by: Steven Hadn <steven@xensource.com>
tools/libxc/xc_misc.c
tools/libxc/xenctrl.h
xen/common/schedule.c
xen/common/sysctl.c
xen/include/public/sysctl.h

index 987eb0eb1336774923bcaa44675699954c8f8039..e17bf7f7218de47ab346330757f844500bc0fc3b 100644 (file)
@@ -109,6 +109,25 @@ int xc_perfc_control(int xc_handle,
     return rc;
 }
 
+int xc_cpuinfo(int xc_handle, int max_cpus, uint64_t *info, int *nr_cpus)
+{
+    int ret;
+    DECLARE_SYSCTL;
+
+    sysctl.cmd = XEN_SYSCTL_cpuinfo;
+    sysctl.u.cpuinfo.max_cpus = max_cpus; 
+    set_xen_guest_handle(sysctl.u.cpuinfo.buffer, info); 
+
+    if ( (ret = do_sysctl(xc_handle, &sysctl)) != 0 )
+        return ret;
+
+    if(nr_cpus) 
+        *nr_cpus = sysctl.u.cpuinfo.nr_cpus; 
+
+    return 0;
+}
+
+
 int xc_hvm_set_pci_intx_level(
     int xc_handle, domid_t dom,
     uint8_t domain, uint8_t bus, uint8_t device, uint8_t intx,
index df71417c7ea41968daca4a2d6f06c32b113ffe2a..26325f0c46ef20be0b7d910e430335c85cdd0283 100644 (file)
@@ -479,6 +479,8 @@ int xc_physinfo(int xc_handle,
 int xc_sched_id(int xc_handle,
                 int *sched_id);
 
+int xc_cpuinfo(int xc_handle, int max_cpus, uint64_t *info, int *nr_cpus); 
+
 int xc_domain_setmaxmem(int xc_handle,
                         uint32_t domid,
                         unsigned int max_memkb);
index 7911f5f99c342cb94cd985cef44bd5485b92add7..17443a44f4c9bae521c22618e481cee27b6daf1a 100644 (file)
@@ -72,8 +72,12 @@ static inline void vcpu_runstate_change(
     ASSERT(v->runstate.state != new_state);
     ASSERT(spin_is_locked(&per_cpu(schedule_data,v->processor).schedule_lock));
 
-    v->runstate.time[v->runstate.state] +=
-        new_entry_time - v->runstate.state_entry_time;
+    if(unlikely((v->runstate.state_entry_time - new_entry_time) > TIME_SLOP))
+        /* Local time on this CPU has been warped */
+        v->runstate.time[v->runstate.state] = new_entry_time; 
+    else 
+        v->runstate.time[v->runstate.state] +=
+            new_entry_time - v->runstate.state_entry_time;
     v->runstate.state_entry_time = new_entry_time;
     v->runstate.state = new_state;
 }
index 0cba2c1164d4358dceaee383d7590803b9a9c321..28cbf9b71f37dce3e0ebab591c077155e0b421ec 100644 (file)
@@ -136,6 +136,38 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl)
     }
     break;
 
+    case XEN_SYSCTL_cpuinfo:
+    {
+        uint32_t i, nr_cpus;
+        uint64_t idletime;
+
+        nr_cpus = (op->u.cpuinfo.max_cpus > NR_CPUS) ? NR_CPUS :
+            op->u.cpuinfo.max_cpus;
+
+        for ( i = 0; i < nr_cpus; i++ )
+        {
+            if(!idle_vcpu[i])
+                /* XXX: assumes no further CPUs after first missing one */
+                break;
+
+            /* somewhat imprecise but should suffice */
+            idletime = idle_vcpu[i]->runstate.time[RUNSTATE_running] +
+                (NOW() - idle_vcpu[i]->runstate.state_entry_time);
+            if ( copy_to_guest_offset(op->u.cpuinfo.buffer, i, &idletime, 1) )
+            {
+                ret = -EFAULT;
+                break;
+            }
+        }
+
+        op->u.cpuinfo.nr_cpus = i;
+        ret = 0;
+
+        if( copy_to_guest (u_sysctl, op, 1) )
+            ret = -EFAULT;
+    }
+    break;
+
     default:
         ret = arch_do_sysctl(op, u_sysctl);
         break;
index e18d7243f6493ff8457a371237fbc699f5129b3d..be20efc4c136906ecaa6ebf0492fc6b194fefc3e 100644 (file)
@@ -152,6 +152,18 @@ struct xen_sysctl_debug_keys {
 typedef struct xen_sysctl_debug_keys xen_sysctl_debug_keys_t;
 DEFINE_XEN_GUEST_HANDLE(xen_sysctl_debug_keys_t);
 
+/* Get physical CPU information */
+#define XEN_SYSCTL_cpuinfo           8
+struct xen_sysctl_cpuinfo {
+    /* IN variables. */
+    uint32_t                      max_cpus;
+    XEN_GUEST_HANDLE_64(uint64_t) buffer;
+    /* IN/OUT variables. */
+    uint32_t                      nr_cpus;
+}; 
+typedef struct xen_sysctl_cpuinfo xen_sysctl_cpuinfo_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_cpuinfo_t); 
+
 struct xen_sysctl {
     uint32_t cmd;
     uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */
@@ -163,6 +175,7 @@ struct xen_sysctl {
         struct xen_sysctl_perfc_op          perfc_op;
         struct xen_sysctl_getdomaininfolist getdomaininfolist;
         struct xen_sysctl_debug_keys        debug_keys;
+        struct xen_sysctl_cpuinfo           cpuinfo;
         uint8_t                             pad[128];
     } u;
 };